package org.ims.inv.web.action.project;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.ims.inv.model.project.ModelProject;
import org.ims.inv.model.project.ModelProjectConference;
import org.ims.inv.model.project.ModelProjectMaterial;
import org.ims.inv.model.project.ModelProjectMaterialMeta;
import org.ims.inv.model.project.ModelProjectProcess;
import org.ims.inv.service.project.ServiceProject;
import org.ims.inv.service.project.ServiceProjectConference;
import org.ims.inv.service.project.ServiceProjectEvent;
import org.ims.inv.service.project.ServiceProjectMaterial;
import org.ims.inv.service.project.ServiceProjectMaterialMeta;
import org.ims.inv.service.project.ServiceProjectProcess;
import org.ims.inv.web.action.BaseAppAction;
import org.ims.inv.web.util.ContextUtil;

import cn.trymore.core.exception.ServiceException;
import cn.trymore.core.log.LogAnnotation;
import cn.trymore.core.util.UtilCollection;
import cn.trymore.core.util.UtilDate;
import cn.trymore.core.util.UtilFile;
import cn.trymore.core.util.UtilString;
import cn.trymore.core.util.UtilZip;

/**
 * Action: 项目基类
 * 
 * @author Jeccy.Zhao
 *
 */
public class ProjectBaseAction
extends BaseAppAction
{
	/**
	 * The LOGGER
	 */
	private static final Logger LOGGER = Logger.getLogger(ProjectBaseAction.class);

	/**
	 * Tab for project form
	 */
	protected static final String TAB_FORM = "form";
	
	/**
	 * Tab for project material
	 */
	protected static final String TAB_MATERIAL = "material";
	
	/**
	 * Event name for initialization
	 */
	protected static final String EVENT_INIT = "项目初始化";
	
	/**
	 * Event name for conference pre-audit
	 */
	protected static final String EVENT_CONFERENCE_PREAUDIT = "过会预审";
	
	/**
	 * Event name for other events
	 */
	protected static final String EVENT_OTHER = "其他";
	
	/**
	 * Service of project
	 */
	protected ServiceProject serviceProject;
	
	/**
	 * Service of project material
	 */
	protected ServiceProjectMaterial serviceProjectMaterial;
	
	/**
	 * Service of project event
	 */
	protected ServiceProjectEvent serviceProjectEvent;
	
	/**
	 * Service of project process
	 */
	protected ServiceProjectProcess serviceProjectProcess;
	
	/**
	 * Service of project meta
	 */
	protected ServiceProjectMaterialMeta serviceProjectMaterialMeta;
	
	/**
	 * Service of project conference
	 */
	protected ServiceProjectConference serviceProjectConference;
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 项目页面 (项目信息, 材料区)
	 */
	public ActionForward dialogProjectPage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		String projectId = request.getParameter("pid");
		try
		{
			if (UtilString.isNotEmpty(projectId))
			{
				ModelProject entity = this.serviceProject.get(projectId);
				if (entity != null)
				{
					this.outWriteAllParameters(request);
					request.setAttribute("entity", entity);
					
					request.setAttribute("users", this.serviceAppUser.getAllUsers());
					
					return mapping.findForward("base.project.dialog.tab");	
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 项目过会预审页面 (项目信息, 材料区)
	 */
	public ActionForward dialogProjectConferencePage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		String conferenceId = request.getParameter("cid");
		try
		{
			if (UtilString.isNotEmpty(conferenceId))
			{
				ModelProjectConference entity = this.serviceProjectConference.get(conferenceId);
				if (entity != null)
				{
					this.outWriteAllParameters(request);
					request.setAttribute("entity", entity);
					
					request.setAttribute("users", this.serviceAppUser.getAllUsers());
					
					return mapping.findForward("base.project.dialog.conference");
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 项目暂停
	 */
	public ActionForward dialogProjectSuspendPage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		String projectId = request.getParameter("pid");
		try
		{
			if (UtilString.isNotEmpty(projectId))
			{
				ModelProject entity = this.serviceProject.get(projectId);
				
				if (entity != null)
				{
					request.setAttribute("entity", entity);
					
					return mapping.findForward("base.project.dialog.suspend");	
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 项目添加材料
	 */
	public ActionForward dialogProjectAddMaterial (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		String projectId = request.getParameter("pid");
		String materialId = request.getParameter("mid");
		
		try
		{
			if (UtilString.isNotEmpty(projectId))
			{
				ModelProject entity = this.serviceProject.get(projectId);
				if (entity != null)
				{
					request.setAttribute("project", entity);
					if (UtilString.isNotEmpty(materialId))
					{
						ModelProjectMaterial material = this.serviceProjectMaterial.get(materialId);
						if (material != null)
						{
							request.setAttribute("material", material);
						}
						else
						{
							return ajaxPrint(response, getErrorCallback("材料数据实体不存在."));
						}
					}
					
					request.setAttribute("currentUser", ContextUtil.getCurrentUser());
					request.setAttribute("date", new Date());
					
					this.outWriteAllParameters(request);
					
					return mapping.findForward("base.project.dialog.file");	
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 历史材料记录
	 */
	public ActionForward dialogProjectMaterialRepository (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		String materialId = request.getParameter("mid");
		try
		{
			if (UtilString.isNotEmpty(materialId))
			{
				if (UtilString.isNotEmpty(materialId))
				{
					ModelProjectMaterial material = this.serviceProjectMaterial.get(materialId);
					if (material != null)
					{
						request.setAttribute("material", material);
					}
					else
					{
						return ajaxPrint(response, getErrorCallback("材料数据实体不存在."));
					}
				}
					
				return mapping.findForward("base.project.dialog.file.repository");	
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 加载项目Tab页面信息 (登记信息, 材料区)
	 */
	public ActionForward actionLoadProjectTab (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String tab = request.getParameter("tab");
			String projectId = request.getParameter("pid");
			
			if (UtilString.isNotEmpty(projectId, tab))
			{
				this.outWriteAllParameters(request);
				
				ModelProject entity = this.serviceProject.get(projectId);
				if (entity != null)
				{
					request.setAttribute("entity", entity);
					
					if (TAB_FORM.equals(tab))
					{
						// 登记信息
						
						request.setAttribute("dictInds", this.getDictionariesByType("DICT_PRO_INDUSTRY"));
						request.setAttribute("dictPtns", this.getDictionariesByType("DICT_PRO_PARTNER"));
						request.setAttribute("recordTime", entity.getProjectCreationTime());
						request.setAttribute("recommendTime", entity.getProjectRecommendedDate());
						request.setAttribute("recordUser", entity.getProjectRecorder());
						request.setAttribute("users", this.serviceAppUser.getAllUsers());
						
						request.setAttribute("projectAttendees", 
								this.converseUidsToObject(entity.getProjectAttendeeIds(), ","));
						
						/*
						request.setAttribute("partnerAttendees", 
								entity.getProjectPartnerAttendeeIds());
						*/
						
						this.outWriteAllParameters(request);
						
						return mapping.findForward("base.project.data.form");
					}
					else if (TAB_MATERIAL.equals(tab))
					{
						
						request.setAttribute("materials", entity.getMaterials());
						
						// 材料区
						return mapping.findForward("base.project.data.material");
					}
					else
					{
						return ajaxPrint(response, getErrorCallback("未知的项目数据加载请求项"));
					}
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 提交材料至审批环节
	 */
	public ActionForward actionPostMaterail (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		String projectId = request.getParameter("projectId");
		String processFormId = request.getParameter("processFormId");
		
		try
		{
			if (UtilString.isNotEmpty(projectId, processFormId))
			{
				ModelProject entity = this.serviceProject.get(projectId);
				if (entity != null)
				{
					// 获取提交至的环节
					ModelProjectProcess toProcess = this.serviceProjectProcess.get(processFormId);
					if (toProcess != null)
					{
						ModelProjectProcess currentProcess = entity.getCurrentProcess();
						if (toProcess.getSequence() > currentProcess.getSequence())
						{
							// 跳跃操作...
							for (ModelProjectProcess proc : entity.getProcessForms())
							{
								if (proc.getSequence() >= currentProcess.getSequence() &&
										proc.getSequence() < toProcess.getSequence())
								{
									proc.setAuditState(ModelProjectProcess.EProjectAuditState.IGNORED.getValue());
									this.serviceProjectProcess.save(proc);
								}
							}
						}
						
						entity.setCurrentProcess(toProcess);
						entity.setProjectStatus(ModelProject.EProjectStatus.APPROVING.getValue());
						this.serviceProject.save(entity);
						
						// 更新审批环节材料上交状态
						toProcess.setMaterialStatus(ModelProjectProcess.EProjectMaterialStatus.POSTED.getValue());
						
						// 存在预审环节
						if (toProcess.getDependedFlow() != null)
						{
							// 设置预审环节状态为`进行中`
							toProcess.setDependedFlowAuditStatus(
									ModelProjectProcess.EProjectDependFlowAuditState.ONGOING.getValue());
						}
						
						this.serviceProjectProcess.save(toProcess);
						
						if (toProcess.getDependedFlow() != null)
						{
							String conferenceTime = request.getParameter("conferTime");
							String reason = request.getParameter("conferReason");
							
							ModelProjectConference conference = new ModelProjectConference();
							conference.setProcess(toProcess);
							conference.setCreationTime(new Date());
							conference.setReason(reason);
							conference.setConferenceTime(UtilDate.toDate(conferenceTime, "yyyy-MM-dd HH:mm"));
							conference.setAuthor(ContextUtil.getCurrentUser());
							
							this.serviceProjectConference.save(conference);
						}
						
						// 记录项目进展
						this.serviceProjectEvent.traceEvent(
								entity, 
								"提交材料", 
								null, 
								"提交至`" + toProcess.getNodeTitle() + "`"
						);
						
						if (toProcess.getSequence().equals(1))
						{
							// 服务器推送至客户端.
							this.getMessagePush().pushMessage(
								this.getAllUserIds(),
								scriptMessageNotify, 
								"menu_item_project_trial",
								1
							);
						}
						else if (toProcess.getSequence().equals(2))
						{
							// 服务器推送至客户端.
							this.getMessagePush().pushMessage(
								this.getAllUserIds(),
								scriptMessageNotify, 
								"menu_item_project_review",
								1
							);
						}
						else 
						{
							if (toProcess.getDependedFlow() != null)
							{
								// 服务器推送至客户端.
								this.getMessagePush().pushMessage(
									this.getAllUserIds(),
									scriptMessageNotify, 
									"menu_item_project_preconfer",
									1
								);
							}
							else
							{
								// 服务器推送至客户端.
								this.getMessagePush().pushMessage(
									this.getAllUserIds(),
									scriptMessageNotify, 
									"menu_item_project_confer",
									1
								);
							}
						}
						
						return ajaxPrint(response, 
								getSuccessCallback("数据保存成功.", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));
					}
					else
					{
						return ajaxPrint(response, getErrorCallback("数据实体不存在."));
					}
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 材料删除
	 */
	public ActionForward actionRemoveMaterails (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String materialId = request.getParameter("mid");
			
			if (UtilString.isNotEmpty(materialId))
			{
				ModelProjectMaterial material = this.serviceProjectMaterial.get(materialId);
				if (material != null)
				{
					if (material.getMetas() != null)
					{
						Iterator<ModelProjectMaterialMeta> itor = material.getMetas().iterator();
						while (itor.hasNext())
						{
							ModelProjectMaterialMeta meta = itor.next();
							meta.setMaterial(null);
							itor.remove();
							this.serviceProjectMaterialMeta.remove(meta);
						}
						
						this.serviceProjectMaterial.save(material);
					}
					
					return ajaxPrint(response, 
							getSuccessCallbackAndReloadCurrent("材料移除成功."));
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * 根据项目名称搜索项目并自动提示
	 * 
	 * @param userName
	 * @return
	 */
	public ActionForward lookupProjectByTitle (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
	{
		String search = request.getParameter("search");
		
		try
		{
			StringBuilder builder = new StringBuilder();
			
			ModelProject entity = new ModelProject();
			entity.setProjectName(search);
			
			List<ModelProject> result = serviceProject.getProjectsByCriterion(entity);
			if (result != null && result.size() > 0)
			{
				int count = 0;
				for (ModelProject project : result)
				{
					count++;
					
					builder.append("{");
					builder.append("\"id\":\"" + project.getId() + "\",");
					builder.append("\"projectName\":\"" + project.getProjectName() + "\",");
					builder.append("\"projectNo\":\"" + project.getProjectNo() + "\"");
					builder.append("}");
					
					if (count < result.size())
					{
						builder.append(",");
					}
				}
				String callbackJson = "[" + builder.toString() + "]";
				return ajaxPrint(response, callbackJson);
			}
		} 
		catch (ServiceException e)
		{
			LOGGER.error("Exception raised when lookup project by name: " + search, e);
		}
		
		return ajaxPrint(response, "[]");
	}
	
	/**
	 * 根据项目编号搜索项目并自动提示
	 * 
	 * @param userName
	 * @return
	 */
	public ActionForward lookupProjectByNo (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
	{
		String search = request.getParameter("search");
		
		try
		{
			StringBuilder builder = new StringBuilder();
			
			ModelProject entity = new ModelProject();
			entity.setProjectNo(search);
			
			List<ModelProject> result = serviceProject.getProjectsByCriterion(entity);
			if (result != null && result.size() > 0)
			{
				int count = 0;
				for (ModelProject project : result)
				{
					count++;
					
					builder.append("{");
					builder.append("\"id\":\"" + project.getId() + "\",");
					builder.append("\"projectName\":\"" + project.getProjectName() + "\",");
					builder.append("\"projectNo\":\"" + project.getProjectNo() + "\"");
					builder.append("}");
					
					if (count < result.size())
					{
						builder.append(",");
					}
				}
				String callbackJson = "[" + builder.toString() + "]";
				return ajaxPrint(response, callbackJson);
			}
		} 
		catch (ServiceException e)
		{
			LOGGER.error("Exception raised when lookup project by name: " + search, e);
		}
		
		return ajaxPrint(response, "[]");
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 打包材料并下载
	 */
	public ActionForward actionPackMaterail (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String pid = request.getParameter("pid");
			if (UtilString.isNotEmpty(pid))
			{
				ModelProject project = this.serviceProject.get(pid);
				
				if (project != null)
				{
					String fileName = project.getProjectName() + ".zip";
					
					// 归类打包
					String archivePath = packProjectMaterials (project, request);
					
					// 生成zip文件
					UtilZip zip = new UtilZip(archivePath + ".zip");
					zip.compress(archivePath);
					
					if (archivePath != null)
					{
						//  写流文件到前端浏览器    
						ServletOutputStream out = response.getOutputStream();
						
						response.setHeader("Content-disposition", "attachment;filename=" + 
								new String(fileName.getBytes("gb2312"), "ISO8859-1" ));
						
						BufferedInputStream bis = null;
						BufferedOutputStream bos = null;
						try {
							bis = new BufferedInputStream(new FileInputStream(archivePath + ".zip"));
							bos = new BufferedOutputStream(out);
							byte[] buff = new byte[2048];
							int bytesRead;
							while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
								bos.write(buff, 0, bytesRead);
							}
						} catch (IOException e) {
							throw e;
						} finally {
							if (bis != null) {
								bis.close();
							}
							if (bos != null) {
								bos.close();
							}
						}
					}
					
				}
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when packing materials..", e);
		}
			
		return null;
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 暂停项目
	 */
	@LogAnnotation(description="暂停项目: `${projectNo}`",type="项目暂停")
	public ActionForward actionSuspendProject (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		String projectId = request.getParameter("id");
		
		try
		{
			if (UtilString.isNotEmpty(projectId))
			{
				ModelProject entity = this.serviceProject.get(projectId);
				
				if (entity != null)
				{
					// 清空当前审批环节
					entity.setCurrentProcess(null);
					
					entity.setProjectStatus(ModelProject.EProjectStatus.SUSPENDED.getValue());
					entity.setSuspendReason(request.getParameter("suspendReason"));
					entity.setArchived(ModelProject.EProjectArchived.ARCHIEVED.getValue());
					entity.setSuspendTime(new Date());
					
					this.serviceProject.save(entity);
					
					// 记录暂停事件
					this.serviceProjectEvent.traceEvent(
						entity, 
						"项目暂停", 
						null, 
						request.getParameter("suspendReason")
					);
					
					// 服务器推送至客户端.
					this.getMessagePush().pushMessage(
							entity.getProjectRelevantPersonIds(),
						scriptMessageNotify, 
						"menu_item_project_track",
						-1
					);
					
					return ajaxPrint(response, 
							getSuccessCallback("数据保存成功.", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在."));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("未知的请求参数."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * 项目材料打包
	 * 
	 * @param project
	 * @return
	 */
	@SuppressWarnings("deprecation")
	private String packProjectMaterials (ModelProject project, HttpServletRequest request)
	{
		if (project != null)
		{
			// 归类
			String uploadPath = request.getRealPath("/uploads/");
			String archivePath = uploadPath + "/archive/" + project.getProjectName() + 
				"_" + UtilDate.parseTime(new Date(), "yyyyMMddHHmm");
			
			UtilFile.createFolder(archivePath);
			
			if (project.getMaterials() != null)
			{
				for (ModelProjectMaterial material : project.getMaterials())
				{
					if (material.getTotalMaterialCount() > 0)
					{
						String rootPath = archivePath + "/" + material.getMaterialName();
						UtilFile.createFolder(rootPath);
						
						if (material.getMaterialChildren() != null)
						{
							for (ModelProjectMaterial sub : material.getMaterialChildren())
							{
								if (sub.getTotalMaterialCount() > 0)
								{
									String subPath = rootPath + "/" + sub.getMaterialName();
									UtilFile.createFolder(subPath);
									
									if (sub.getMetas() != null)
									{
										for (ModelProjectMaterialMeta meta : sub.getMetas())
										{
											if (meta != null && meta.getAttachment() != null)
											{
												try
												{
													UtilFile.copyFile(
															new File(uploadPath + "/" + meta.getAttachment().getFilePath()), 
															new File(subPath + "/" + meta.getAttachment().getFileName())
													);
												}
												catch (Exception e)
												{
													LOGGER.error("Exception raised when copying file," + 
															meta.getAttachment().getFilePath(), e);
												}
											}
										}
									}
								}
							}
						}
						
					}
				}
			}
			
			return archivePath;
		}
		
		return null;
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 项目恢复
	 */
	public ActionForward actionRecoverProject (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String projectId = request.getParameter("pid");
			if (this.isObjectIdValid(projectId))
			{
				ModelProject entity = this.serviceProject.get(projectId);
				if (entity != null)
				{
					ModelProjectProcess toProcess = null;
					Integer projectStatus = entity.getProjectStatus();
					if (ModelProject.EProjectStatus.SUSPENDED.getValue().equals(projectStatus))
					{
						// 储备项目
						entity.setSuspendReason(null);
						entity.setArchived(null);
						entity.setSuspendTime(null);
					}
					else if (ModelProject.EProjectStatus.REJECTED.getValue().equals(projectStatus))
					{
						// 否决项目
						
					}
					
					for (ModelProjectProcess process : entity.getProcessForms())
					{
						if (process.getAuditState() == null)
						{
							toProcess = process; 
							break;
						}
					}
					
					if (toProcess.getMaterialStatus().equals(
							ModelProjectProcess.EProjectMaterialStatus.POSTED.getValue()))
					{
						// 材料已上交
						entity.setProjectStatus(ModelProject.EProjectStatus.APPROVING.getValue());
					}
					else
					{
						// 材料待上交
						entity.setProjectStatus(ModelProject.EProjectStatus.TOPOST.getValue());
					}
							
					entity.setCurrentProcess(toProcess);
					
					this.serviceProject.save(entity);
					
					// 记录恢复事件
					this.serviceProjectEvent.traceEvent(
						entity, 
						"项目恢复", 
						null, 
						"项目恢复至: " + toProcess.getNodeTitle()
					);
					
					if (toProcess.getSequence().equals(1))
					{
						// 服务器推送至客户端.
						this.getMessagePush().pushMessage(
							this.getAllUserIds(),
							scriptMessageNotify, 
							"menu_item_project_trial",
							1
						);
					}
					else if (toProcess.getSequence().equals(2))
					{
						// 服务器推送至客户端.
						this.getMessagePush().pushMessage(
							this.getAllUserIds(),
							scriptMessageNotify, 
							"menu_item_project_review",
							1
						);
					}
					else 
					{
						if (toProcess.getDependedFlow() != null)
						{
							// 服务器推送至客户端.
							this.getMessagePush().pushMessage(
								this.getAllUserIds(),
								scriptMessageNotify, 
								"menu_item_project_preconfer",
								1
							);
						}
						else
						{
							// 服务器推送至客户端.
							this.getMessagePush().pushMessage(
								this.getAllUserIds(),
								scriptMessageNotify, 
								"menu_item_project_confer",
								1
							);
						}
					}
						
					return ajaxPrint(response, 
							getSuccessCallback("项目恢复成功..", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("项目不存在:" + projectId));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("非法项目ID:" + projectId));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when processing project recovery", e);
			return ajaxPrint(response, getErrorCallback("项目恢复失败:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 纠正项目数据
	 */
	public ActionForward actionCorrectProject (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			List<ModelProject> projects = this.serviceProject.getAll();
			if (UtilCollection.isNotEmpty(projects))
			{
				for (ModelProject project : projects)
				{
					String projectNo = project.getProjectNo();
					Date postTime = project.getProjectPostTime();
					
					Integer noYear = Integer.valueOf(projectNo.substring(0, 2));
					Integer noMonth = Integer.valueOf(projectNo.substring(2, 4));
					Integer postYear = Integer.valueOf(UtilDate.parseTime(postTime, "yy"));
					Integer postMonth = Integer.valueOf(UtilDate.parseTime(postTime, "MM"));
					
					if (noYear < postYear || noMonth < postMonth)
					{
						String newPostTime = "20" + noYear + "-" + noMonth + "-" + 
								UtilDate.parseTime(postTime, "dd HH:mm:ss");
						
						project.setProjectPostTime(UtilDate.toDate(newPostTime, "yyyy-MM-dd HH:mm:ss"));
						this.serviceProject.save(project);
					}
				}
			}
			
			return null;
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	public void setServiceProject(ServiceProject serviceProject)
	{
		this.serviceProject = serviceProject;
	}

	public ServiceProject getServiceProject()
	{
		return serviceProject;
	}

	public void setServiceProjectMaterial(ServiceProjectMaterial serviceProjectMaterial)
	{
		this.serviceProjectMaterial = serviceProjectMaterial;
	}

	public ServiceProjectMaterial getServiceProjectMaterial()
	{
		return serviceProjectMaterial;
	}

	public void setServiceProjectEvent(ServiceProjectEvent serviceProjectEvent)
	{
		this.serviceProjectEvent = serviceProjectEvent;
	}

	public ServiceProjectEvent getServiceProjectEvent()
	{
		return serviceProjectEvent;
	}

	public static Logger getLogger()
	{
		return LOGGER;
	}

	public void setServiceProjectProcess(ServiceProjectProcess serviceProjectProcess)
	{
		this.serviceProjectProcess = serviceProjectProcess;
	}

	public ServiceProjectProcess getServiceProjectProcess()
	{
		return serviceProjectProcess;
	}

	public void setServiceProjectMaterialMeta(ServiceProjectMaterialMeta serviceProjectMaterialMeta)
	{
		this.serviceProjectMaterialMeta = serviceProjectMaterialMeta;
	}

	public ServiceProjectMaterialMeta getServiceProjectMaterialMeta()
	{
		return serviceProjectMaterialMeta;
	}

	public void setServiceProjectConference(ServiceProjectConference serviceProjectConference)
	{
		this.serviceProjectConference = serviceProjectConference;
	}

	public ServiceProjectConference getServiceProjectConference()
	{
		return serviceProjectConference;
	}
	
}
